/*
 * colas.c
 *
 *  Created on: 20/09/2011
 *      Author: utn_so
 *
 *
 *      Manejo de Colas para cluster
 *      Manejo de Colas para listar archivos y directorios
 *      Manejo de Colas para bloques (no se usa) y bloquesFAT
 *      Manejo de Colas para clusters libres
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "colas.h"
#include<pthread.h>
#include "iniciarFat.h"








/*Crea la cola */
void CrearColaCluster(struct colaCluster *cola)
{
	cola->frente = 0;
	cola->final = 0;
}

/*Inserta el nodo en la parte final de la cola*/

void MeterEnColaCluster (struct colaCluster *cola, uint32_t x)
{
	struct nodoColaCluster *nuevo;
	nuevo=(struct nodoColaCluster *)malloc(sizeof(struct nodoColaCluster));
	nuevo->numero = x;
	nuevo->sgte = NULL;

	if(ColaClusterVacia(*cola))
		cola->frente = nuevo;
	else
		cola->final->sgte = nuevo;

	cola->final = nuevo;

}

/*elimina el elemento que esta aL frente de la cola*/

uint32_t SacarDeColaCluster (struct colaCluster *cola)
{
	uint32_t temp;

	if(!ColaClusterVacia(*cola))
	{
		struct nodoColaCluster *nuevo;
		nuevo = cola->frente;
		temp = cola->frente->numero;
		cola->frente = cola->frente->sgte;
		free(nuevo);
		if (cola->frente == NULL)
			cola->final = NULL;
	}
	else
		printf("ERROR, cola vacia, se puede eliminar\a\n");

return (temp);
}

uint32_t ColaClusterVacia(struct colaCluster cola)
{
	return (cola.frente==NULL);
}



/*Crea la cola */
void CrearColaArchivos(struct colaArchivos *cola)
{
	cola->frente = cola->final = NULL;
}

/*Inserta el nodo en la parte final de la cola*/

void MeterEnColaArchivos (struct colaArchivos *cola, char *nombre, char esCarpeta)
{
	struct nodoColaArchivos *nuevo;
	nuevo=(struct nodoColaArchivos *)malloc(sizeof(struct nodoColaArchivos));
	strcpy(nuevo->nombreArchivo, nombre);
	nuevo->esCarpeta= esCarpeta;
	nuevo->sgte=NULL;

	if(ColaArchivosVacia(*cola))
		cola->frente=nuevo;
	else
		cola->final->sgte=nuevo;

	cola->final=nuevo;
}

/*elimina el elemento que esta aL frente de la cola*/

char *SacarDeColaArchivos (struct colaArchivos *cola)
{
	//char temp[13+1];
	char *temp;
	temp = (char *) malloc (13+1);

	if(!ColaArchivosVacia(*cola))
	{
		struct nodoColaArchivos *nuevo;
		nuevo=cola->frente;
		strcpy(temp , cola->frente->nombreArchivo);
		cola->frente=cola->frente->sgte;
		free(nuevo);
	}
	else
		printf("ERROR, cola vacia, se puede eliminar\a\n");

return (temp);
}

uint32_t ColaArchivosVacia(struct colaArchivos cola)
{
	return (cola.frente==NULL);
}

void CrearColaBloque (struct colaBloques *cola)
{
	cola->frente = cola->final = NULL;
}


void MeterEnColaBloque (struct colaBloques *cola, uint32_t x)  /* x es un sector */
{
	int32_t numeroBloque;
	numeroBloque = x / 8; 	/* la parte entera de (número de sector / 8) es el número de bloques */
							/* 8 es el número de sectores que tiene el bloque */

	if ( (cola->final->numero) == numeroBloque ) /* si el bloque ya está en cola no lo agrego, sólo le sumo el contador */
	{	/* si el bloque está en la cola, sólo podría estar al final */
		(cola->final->cantidadSectores)++;
	}
	else	/* Sino, agrego el bloque e inicializo su contador en 1 */
	{
		struct nodoColaBloques *nuevo;
		nuevo=(struct nodoColaBloques *)malloc(sizeof(struct nodoColaBloques));
		nuevo->numero = numeroBloque;
		nuevo->cantidadSectores = 1;
		nuevo->sgte=NULL;

		if(ColaBloqueVacia(*cola))
			cola->frente=nuevo;
		else
			cola->final->sgte=nuevo;

		cola->final=nuevo;

	}
};


uint32_t SacarDeColaBloque (struct colaBloques *cola) 	/* devuelve el número de bloque */
/* sólo se usa para los bloques intermedios de la cola de bloques*/
/* el bloque frente y fin tienen tratamiento diferente */
{
	uint32_t temp;

	if(!ColaBloqueVacia(*cola))
	{
		struct nodoColaBloques *nuevo;
		nuevo=cola->frente;
		temp=cola->frente->numero;
		cola->frente = cola->frente->sgte;
		free(nuevo);


	}
	else
		printf("ERROR, cola vacia, se puede eliminar\a\n");

return (temp);
};

uint32_t ColaBloqueVacia(struct colaBloques cola)
{
	return (cola.frente==NULL);
};


void CrearColaBloqueFAT (struct colaBloquesFAT *cola)
{
	cola->final = NULL;
	cola->frente = NULL;
}

void MeterEnColaBloqueFAT (struct colaBloquesFAT *cola, uint32_t x) //no agrega repetidos en la cola
{

	struct nodoColaBloquesFAT *ptr;

	struct nodoColaBloquesFAT *nuevo;
	nuevo=(struct nodoColaBloquesFAT *)malloc(sizeof(struct nodoColaBloquesFAT));
	nuevo->numero = x;
	nuevo->sgte=NULL;

	if(ColaBloqueVaciaFAT(*cola))
		cola->frente=nuevo;
	else
	{
		ptr = cola->frente;
		while (ptr != NULL)
			if (ptr->numero != x)
				ptr = ptr->sgte;
			else
			{
				free(nuevo);
				return;
			}


		cola->final->sgte=nuevo;
	}
	cola->final=nuevo;

	return;

}

uint32_t SacarDeColaBloqueFAT(struct colaBloquesFAT *cola)
{
		uint32_t temp = 0;

		if(!ColaBloqueVaciaFAT(*cola))
		{
			struct nodoColaBloques *nuevo;
			nuevo=cola->frente;
			temp=cola->frente->numero;
			cola->frente = cola->frente->sgte;



		}
		else
			printf("ERROR, cola vacia, se puede eliminar\a\n");

	return (temp);
}

uint32_t ColaBloqueVaciaFAT(struct colaBloquesFAT cola)
{
	return (cola.frente==NULL);
}

/* En cluster.c
void CrearColaClusterLibres(struct colaClusterLibres *cola)
{
	cola->frente = 0;
	cola->final = 0;
}
*/

/*Inserta el nodo en la parte final de la cola*/

void MeterEnColaClusterLibres (struct colaClusterLibres *cola, uint32_t x)
{
	struct nodoColaClusterLibres *nuevo;
	nuevo=(struct nodoColaClusterLibres *)malloc(sizeof(struct nodoColaClusterLibres));
	nuevo->numero = x;
	nuevo->sgte = NULL;

	if(ColaClusterVaciaLibres(*cola))
		cola->frente = nuevo;
	else
		cola->final->sgte = nuevo;

	cola->final = nuevo;
	cola->cantidadNodosLibres++;

}

/*elimina el elemento que esta aL frente de la cola*/

uint32_t SacarDeColaClusterLibres (struct colaClusterLibres *cola)
{
	uint32_t temp;
	pthread_mutex_lock(&mutexClustersLibres);

	if(!ColaClusterVaciaLibres(*cola))
	{
		struct nodoColaClusterLibres *nuevo;
		nuevo = 		cola->frente;
		temp = 			cola->frente->numero;
		cola->frente = 	cola->frente->sgte;
		cola->cantidadNodosLibres--;
		free(nuevo);
	}

	else
		printf("ERROR, cola vacia, se puede eliminar\a\n");

	pthread_mutex_unlock(&mutexClustersLibres);

return (temp);
}

uint32_t ColaClusterVaciaLibres(struct colaClusterLibres cola)
{
	return (cola.frente==NULL);
}


